介绍
DrawerLayout是Support Library包中实现了侧滑菜单效果的控件 android.support.v4.widget.DrawerLayout NavigationView是一个导航菜单框架,使用menu资源填充数据 常用来配合DrawerLayout使用
基本使用 DrawerLayout 布局文件 1 2 3 4 5 6 7 <android.support.v4.widget.DrawerLayout xmlns:android ="http://schemas.android.com/apk/res/android" xmlns:app ="http://schemas.android.com/apk/res-auto" android:id ="@+id/drawerlayout" android:layout_width ="match_parent" android:layout_height ="match_parent" > …… </android.support.v4.widget.DrawerLayout >
使用DrawerLayout的时候需要将该布局作为根布局,然后在DrawerLayout中添加其他布局作为显示界面。
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 drawerLayout = (DrawerLayout) findViewById(R.id.drawerlayout);获取DrawerLayout对象 drawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() { @Override public void onDrawerSlide (View drawerView, float slideOffset) { Log.e(TAG , " onDrawerSlide slideOffset = " + slideOffset); } @Override public void onDrawerOpened (View drawerView) { Log.e(TAG , " onDrawerOpened " ); } @Override public void onDrawerClosed (View drawerView) { Log.e(TAG , " onDrawerClosed " ); } @Override public void onDrawerStateChanged (int newState) { Log.e(TAG , " onDrawerStateChanged " ); } });
DrawerLayout的状态监听,listener的回调提供给开发者使用。
NavigationView 布局文件 header.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android ="http://schemas.android.com/apk/res/android" android:layout_width ="match_parent" android:layout_height ="240dp" android:background ="@color/colorPrimaryDark" android:orientation ="vertical" > //引用GitHub上的开源库 <de.hdodenhof.circleimageview.CircleImageView android:id ="@+id/civ_profile" android:layout_width ="150dp" android:layout_height ="150dp" android:layout_alignParentLeft ="true" android:layout_marginLeft ="24dp" android:layout_marginStart ="24dp" android:layout_marginTop ="20dp" android:src ="@drawable/logo" /> <TextView android:id ="@+id/tv_name" android:layout_width ="wrap_content" android:layout_height ="wrap_content" android:layout_alignLeft ="@+id/civ_profile" android:layout_below ="@+id/civ_profile" android:layout_marginTop ="10dp" android:text ="Askmak Sharon" android:textColor ="#FFFFFF" android:textSize ="8pt" android:textStyle ="bold" /> <TextView android:id ="@+id/tv_email" android:layout_width ="wrap_content" android:layout_height ="wrap_content" android:layout_alignLeft ="@+id/civ_profile" android:layout_below ="@+id/tv_name" android:layout_marginTop ="10dp" android:text ="onlyloveyd@gmail.com" android:textColor ="#FFFFFF" android:textSize ="8pt" android:textStyle ="italic" /> </RelativeLayout >
这里使用了Github上的开关库de.hdodenhof.circleimageview.CircleImageView ,其中可以设置一些属性,这里没有设置,可能是因为我使用的图片风格的原因,将头像的边框加上去后看上去不是那么协调
属性
意义
app:civ_border_color=””
边框颜色
app:civ_border_width=””
边框宽度
app:civ_fill_color=””
填充颜色
second_menu.xml 这里只是名字叫做second_menu而已,没有其他的意思,只是一个普通的menu资源文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android ="http://schemas.android.com/apk/res/android" > <item android:id ="@+id/nv_profile" android:icon ="@drawable/profile" android:orderInCategory ="80" android:title ="Profile" /> <item android:id ="@+id/nv_video" android:icon ="@drawable/video" android:orderInCategory ="90" android:title ="Video" /> <item android:id ="@+id/nv_help" android:icon ="@drawable/help" android:orderInCategory ="100" android:title ="Help" /> </menu >
这个menu资源是用来在NavigationView中使用的导航菜单
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android ="http://schemas.android.com/apk/res/android" xmlns:app ="http://schemas.android.com/apk/res-auto" android:id ="@+id/drawerlayout" android:layout_width ="match_parent" android:layout_height ="match_parent" > <LinearLayout android:orientation ="vertical" android:layout_width ="match_parent" android:layout_height ="match_parent" > <include layout ="@layout/toolbar" > </include > <FrameLayout android:id ="@+id/frame" android:layout_width ="match_parent" android:layout_height ="match_parent" > <ImageView android:id ="@+id/content_iv" android:layout_gravity ="center" android:layout_width ="match_parent" android:layout_height ="match_parent" android:src ="@mipmap/ic_launcher" /> </FrameLayout > </LinearLayout > <android.support.design.widget.NavigationView android:id ="@+id/nv_left" android:layout_width ="240dp" android:layout_height ="match_parent" android:layout_gravity ="start" app:headerLayout ="@layout/header" app:menu ="@menu/second_menu" > </android.support.design.widget.NavigationView > </android.support.v4.widget.DrawerLayout >
比较关键的几个点 android:layout_gravity=“start” app:headerLayout=”@layout/header”//头布局 app:menu=”@menu/second_menu”//菜单资源
代码 MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 package mraz.com.actionbardemo;import android.os.Bundle;import android.support.design.widget.NavigationView;import android.support.design.widget.Snackbar;import android.support.v4.view.MenuItemCompat;import android.support.v4.widget.DrawerLayout;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.SearchView;import android.support.v7.widget.Toolbar;import android.util.Log;import android.view.Gravity;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.ImageView;public class MainActivity extends AppCompatActivity { public static String TAG = "yidong" ; DrawerLayout drawerLayout; NavigationView navigationView; Toolbar toolbar; ImageView imageView; @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); drawerLayout = (DrawerLayout) findViewById(R.id.drawerlayout); toolbar = (Toolbar) findViewById(R.id.toolbar); navigationView = (NavigationView) findViewById(R.id.nv_left); imageView = (ImageView) findViewById(R.id.content_iv); setSupportActionBar(toolbar); toolbar.setNavigationIcon(R.drawable.ic_menu_black_24dp); drawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() { @Override public void onDrawerSlide (View drawerView, float slideOffset) { Log.e(TAG , " onDrawerSlide slideOffset = " + slideOffset); } @Override public void onDrawerOpened (View drawerView) { Log.e(TAG , " onDrawerOpened " ); } @Override public void onDrawerClosed (View drawerView) { Log.e(TAG , " onDrawerClosed " ); } @Override public void onDrawerStateChanged (int newState) { Log.e(TAG , " onDrawerStateChanged " ); } }); navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected (MenuItem item) { if (drawerLayout.isDrawerOpen(Gravity.LEFT)) drawerLayout.closeDrawer(Gravity.LEFT); switch (item.getItemId()) { case R.id.nv_profile: imageView.setImageResource(R.drawable.profile); break ; case R.id.nv_video: imageView.setImageResource(R.drawable.video); break ; case R.id.nv_help: imageView.setImageResource(R.drawable.help); break ; } return true ; } }); } …… }
针对NavigationView中的Menu设置响应事件,使用的方式和上一篇中ActionBar中的菜单资源使用方式相似,都是用过getItemId获取资源的id,然后以此作为依据进行对应的响应操作
ActionBar和DrawerLayout配合 一般用户的操作就是右滑或者点击ActionBar左上角的Icon出现左侧抽屉菜单 左侧滑动上面的内容已经实现了,点击ActionBar实现抽屉菜单的开关只需要针对左上角的ActionBar的图标做对应的事件处理即可。
1 2 setSupportActionBar(toolbar); toolbar.setNavigationIcon(R.drawable.ic_menu_black_24dp);
然后在onOptionsItemSelected中
1 2 3 4 5 case android.R.id.home: if (!drawerLayout.isDrawerOpen(Gravity.LEFT)) { drawerLayout.openDrawer(Gravity.LEFT, true ); } break ;
因为ActionBar的NavigationIcon对应的资源ID就是 android.R.id.home 根据这个资源ID定制对应的事件响应,上面就是简单的打开左侧的抽屉菜单
效果图 NavigationView菜单响应
ActionBar左上角图标响应
####源代码 ###点击下载源代码###